package cn.dglydrpy.study.ssm.common.json;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections4.map.LinkedMap;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.junit.Test;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;

/**
 * @Description:  fastjson的使用
 *  com.alibaba.fastjson.JSON  API
public static final Object parse(String text); // 把JSON文本parse为JSONObject或者JSONArray 
public static final JSONObject parseObject(String text)； // 把JSON文本parse成JSONObject    
public static final <T> T parseObject(String text, Class<T> clazz); // 把JSON文本parse为JavaBean 
public static final JSONArray parseArray(String text); // 把JSON文本parse成JSONArray 
public static final <T> List<T> parseArray(String text, Class<T> clazz); //把JSON文本parse成JavaBean集合 
public static final String toJSONString(Object object); // 将JavaBean序列化为JSON文本 
public static final String toJSONString(Object object, boolean prettyFormat); // 将JavaBean序列化为带格式的JSON文本 
public static final Object toJSON(Object javaObject); //将JavaBean转换为JSONObject或者JSONArray。
 * @author:LY_飘涯
 * @date:2019年10月5日 上午12:38:29 
 * @version:1.0
 */
public class JsonTest {
	
	@Test
	public void testParseJson() throws IOException {
		File file = new File(JsonTest.class.getResource("/wangxiaoer.json").getFile());
		String content = FileUtils.readFileToString(file);
		JSONObject jo = JSON.parseObject(content);
		System.out.println("姓名是:"+jo.getString("name"));
		if(!StringUtils.isEmpty(jo.get("nickname"))) {//判空
			System.out.println("昵称是:"+jo.getString("nickname"));
		}
		
		System.out.println("年龄:"+jo.getDouble("age"));
		System.out.println("是否有女朋友?:"+jo.getBoolean("has_girlfriend"));
		JSONArray majorArray = JSONArray.parseArray(jo.getString("major"));
		for(int i=0;i<majorArray.size();i++) {
			String m = majorArray.getString(i);
			System.out.println("专业"+(i+1)+": "+m);
		}
	}
	
	@Test
	public void  creaateJsonObject() {
		System.out.println("1.直接创建JSON对象:");
		getJsonObject();
		System.out.println("2.通过map创建JSON对象:");
		getJsonObjectByMap();
		System.out.println("3.通过javaBean创建JSON对象:"); //json中无日期类型
		getJsonObjectByBean();
	}
	
	private static void getJsonObjectByBean() {
		// TODO Auto-generated method stub
		Person wangxiaoer = new Person();
		wangxiaoer.setName("wangxiaoer");
		wangxiaoer.setAge(25);
		
		wangxiaoer.setBirthday("1990-01-01");
		wangxiaoer.setSchool("蓝翔");
		wangxiaoer.setMajor(new String[] {"理发","挖掘机"});
		wangxiaoer.setHas_girlfriend(false);
		wangxiaoer.setCar(null);
		wangxiaoer.setHouse(null);
		wangxiaoer.setComment("这是一个注释");
		
		System.out.println(JSON.toJSONString(wangxiaoer)); //字符串数组为何显示异常???
	}

	private static void getJsonObjectByMap() {
		
		Map<String,Object> wangxiaoer = new HashMap<String,Object>();
		Object nullObject = null;
		wangxiaoer.put("name","王小二");
		wangxiaoer.put("age", 25);
		wangxiaoer.put("birthday", "1990-01-01");
		wangxiaoer.put("school", "蓝翔");
		wangxiaoer.put("major", new String[] {"理发","挖掘机"});
		wangxiaoer.put("has_girlfriend", false);
		wangxiaoer.put("car", nullObject );
		wangxiaoer.put("house", nullObject );
		wangxiaoer.put("comment","这是一个注解" );
		System.out.println(new JSONObject(wangxiaoer).toString());//车房没有 显示null
	}

	private static void getJsonObject() {
		JSONObject wangxiaoer = new JSONObject();
		Object nullObject = null;
		try {
			wangxiaoer.put("name","王小二");
			wangxiaoer.put("age", 25);
			wangxiaoer.put("birthday", "1990-01-01");
			wangxiaoer.put("school", "蓝翔");
			wangxiaoer.put("major", new String[] {"理发","挖掘机"});
			wangxiaoer.put("has_girlfriend", false);
			wangxiaoer.put("car", nullObject);
			wangxiaoer.put("house", nullObject);
			wangxiaoer.put("comment","这是一个注解" );
			System.out.println(wangxiaoer.toString()); //车房没有 不显示
		} catch (JSONException e) {
			e.printStackTrace();
		}
	}
	
	/**
     * 读取类路径下的配置文件
     * 解析成对象数组并返回
     * @throws IOException
     */
    @Test
    public List<Query> parseQuery() throws IOException {
        // 读取类路径下的query.json文件
        ClassLoader cl = this.getClass().getClassLoader();
        InputStream inputStream = cl.getResourceAsStream("query.json");
        String jsontext = IOUtils.toString(inputStream, "utf8");
        // 先将字符jie串转为List数组
        List<Query> queryList = JSON.parseArray(jsontext, Query.class);
        for (Query query : queryList) {
            List<Column> columnList = new ArrayList<Column>();
            List<LinkedMap<String,Object>> columns = query.getColumn();
            for (LinkedMap<String, Object> linkedMap : columns) {
                //将map转化为java实体类
                Column column = (Column)map2Object(linkedMap, Column.class);
                System.out.println(column.toString());
                columnList.add(column);
            }
            query.setColumnList(columnList); //为columnList属性赋值
        }
        return queryList;
    }

    /**
     * Map转成实体对象
     * @param map map实体对象包含属性
     * @param clazz 实体对象类型
     * @return
     */
    public static Object map2Object(Map<String, Object> map, Class<?> clazz) {
        if (map == null) {
            return null;
        }
        Object obj = null;
        try {
            obj = clazz.newInstance();
            Field[] fields = obj.getClass().getDeclaredFields();
            for (Field field : fields) {
                int mod = field.getModifiers();
                if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
                    continue;
                }
                field.setAccessible(true);
                String flag = (String) map.get(field.getName());
                if(flag != null){
                    if(flag.equals("false") || flag.equals("true")){
                        field.set(obj, Boolean.parseBoolean(flag));
                    }else{
                        field.set(obj, map.get(field.getName()));
                    }
                }                
            }
        } catch (Exception e) {
            e.printStackTrace();
        } 
        return obj;
    }
}
